﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OOLib
{
   /// <summary>
   /// is an abstract service for a component which offers a deeper integration of desktop components than a ::com::sun::star::awt::XWindow can offer 
   /// </summary>
   /// <remarks>
   /// Such components can be loaded into a Frame inside a Desktop environment. A controller is a richer component then a pure window, 
   /// but full featured components need a XModel interface too. 
   /// (see service ::com::sun::star::document::OfficeDocument for further information)
   /// </remarks>
   public class Controller : Component
   {
      #region Constructors

      /// <summary>
      /// Constructor
      /// </summary>
      /// <remarks>
      /// After using this constructor, the ComObj must be set manually!
      /// </remarks>
      public Controller() :
         base()
      { }

      /// <summary>
      /// Constructor
      /// </summary>
      /// <param name="comObject">COM object</param>
      public Controller(object comObject) :
         base(comObject)
      { }

      #endregion

      #region XController

      /// <summary>
      /// Is called to attach the controller with its managing frame
      /// </summary>
      /// <param name="frame">The new owner frame of this controller</param>
      /// <remarks>!!! Not tested !!!</remarks>
      public void AttachFrame(Frame frame)
      {
         CheckDisposed();
         InvokeMethod("attachFrame", frame.ComObj);
      }

      /// <summary>
      /// Is called to attach the controller to a new model. 
      /// </summary>
      /// <param name="model">The new model for this controller</param>
      /// <returns>Returns true if attach was successfully, false otherwise</returns>
      /// <remarks>!!! Not tested !!!</remarks>
      public bool AttachModel(IModel model)
      {
         CheckDisposed();
         var cow = model as ComObjectWrapper;
         if (cow == null)
         {
            throw new ArgumentException("model must be an ComObjectWrapper");
         }
         return (bool)InvokeMethod("attachModel", cow.ComObj);
      }

      /// <summary>
      /// Is called to prepare the controller for closing the view.
      /// </summary>
      /// <param name="suspend">true force the controller to suspend his work, false try to reactivate the controller</param>
      /// <returns>true if request was accepted and of course successfully finished, false otherwise</returns>
      /// <remarks>!!! Not tested !!!</remarks>
      public bool Suspend(bool suspend)
      {
         CheckDisposed();
         return (bool)InvokeMethod("suspend", suspend);
      }

      /// <summary>
      /// Provides access to current view status.
      /// </summary>
      /// <returns>Set of data that can be used to restore the current view status at later time by using XController::restoreViewData()</returns>
      /// <remarks>!!! Not tested !!!</remarks>
      public object GetViewData()
      {
         CheckDisposed();
         return InvokeMethod("getViewData");
      }

      /// <summary>
      /// Restores the view status using the data gotten from a previous call to XController::getViewData().
      /// </summary>
      /// <param name="data">Set of data to restore it </param>
      /// <remarks>!!! Not tested !!!</remarks>
      public void RestoreViewData(object data)
      {
         CheckDisposed();
         InvokeMethod("resoreViewData", data);
      }

      /// <summary>
      /// Gets the currently attached model.
      /// </summary>
      /// <remarks>
      /// This property returns a C# object.
      /// Currently this must be one of the following types (services):
      /// <list type="unordered">
      /// <item>OfficeDocument (com.sun.star.document.OfficeDocument)</item>
      /// </list>
      /// For other types (services) use the property RawModel.
      /// !!! Not tested !!!
      /// </remarks>
      public IModel Model
      {
         get
         {
            var model = RawModel;
            try
            {
               if ((bool)InvokeMethodOf(model, "supportsService", "com.sun.star.document.OfficeDocument"))
               {
                  return GetObjectWrapper<OfficeDocument>(model);
               }
            }
            catch { }
            return null;
         }
      }

      /// <summary>
      /// Gets the currently attached model.
      /// </summary>
      /// <remarks>
      /// This is the raw OpenOffice model.
      /// Use property Model to get a C# object.
      /// !!! Not tested !!!
      /// </remarks>
      public object RawModel
      {
         get
         {
            CheckDisposed();
            return InvokeMethod("getModel");
         }
      }

      /// <summary>
      /// Gets the owner frame of this controller.
      /// </summary>
      public Frame Frame
      {
         get
         {
            CheckDisposed();
            return GetObjectWrapper<Frame>(InvokeMethod("getFrame"));
         }
      }

      #endregion
   }
}
